﻿using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
using System;
using System.Collections;
using System.Collections.Generic;

namespace Assetbundles
{
    public enum LogMode
    {
        All,
        JustError,
    }

    public enum LogType
    {
        Info,
        Warning,
        Error,
    }

    public class LoadedAssetbundle
    { 
        public AssetBundle _assetbundle;
        public int _referenceCount;
        internal event Action onUnloadHandler;
        public void OnUnload()
        {
            _assetbundle.Unload(false);
            if(null!=onUnloadHandler)
            {
                onUnloadHandler();
            }
        }

        public LoadedAssetbundle(AssetBundle assetbundle)
        {
            _assetbundle = assetbundle;
            _referenceCount = 1;
        }
    }

    public class AssetbundleManager : MonoBehaviour
    {
        public delegate string OverrideBaseDownloadingURLDelegate(string bundleName);
        public static OverrideBaseDownloadingURLDelegate overrideBaseDownloadingURLHandler;

        private static LogMode _logMode = LogMode.All;
        public static LogMode LogMode
        {
            get { return _logMode; }
            set { _logMode = value; }
        }

        private static string _baseDownLoadingURL = "";
        public static string BaseDownLoadingURL
        {
            get { return _baseDownLoadingURL; }
            set { _baseDownLoadingURL = value; }
        }

        private static string[] _activeVariants = { };
        public static string[] ActiveVariants
        {
            get { return _activeVariants; }
            set { _activeVariants = value; }
        }

        private static AssetBundleManifest _assetbundleManifest;
        public static AssetBundleManifest AssetBundleManifest
        {
            set { _assetbundleManifest = value; }
        }

        private static Dictionary<string, LoadedAssetbundle> _name_LoadedAssetbundle_Dic = new Dictionary<string, LoadedAssetbundle>();
        private static Dictionary<string, string> _name_Error_Dic = new Dictionary<string, string>();
        private static List<string> _downloadingbundle_List = new List<string>();
        private static List<AssetbundlebaseLoadOperation> _inProgressOperations_List = new List<AssetbundlebaseLoadOperation>();
        private static Dictionary<string, string[]> _name_DependentNames_Dic = new Dictionary<string, string[]>();

#if UNITY_EDITOR
        private static int _simulateAssetbundleInEditor = -1;
        public static bool SimulateAssetbundleInEditor
        {
            get
            {
                if (-1 == _simulateAssetbundleInEditor)
                    _simulateAssetbundleInEditor = EditorPrefs.GetBool(_kSimulateAssetBundles, true) ? 1 : 0;
                return 0 != _simulateAssetbundleInEditor;
            }
            set
            {
                int newValue = value ? 1 : 0;
                if(newValue!=_simulateAssetbundleInEditor)
                {
                    _simulateAssetbundleInEditor = newValue;
                    EditorPrefs.SetBool(_kSimulateAssetBundles,value);
                }
            }
        }
        private const string _kSimulateAssetBundles = "SimulateAssetbundles";
#endif

        private static void Log(LogType logType,string text)
        {
            if(LogType.Error== logType)
            {
                Debug.LogError("[AssetbundleManager] " + text);
            }
            else if(LogMode.All==_logMode&&LogType.Warning==logType)
            {
                Debug.LogWarning("[AssetbundleManager] " + text);
            }
            else if(LogMode.All==_logMode)
            {
                Debug.Log("[AssetBundleManager] " + text);
            }
        }

        private static string GetStreamingAssetsPath()
        {
            if (Application.isEditor)
                return "file:///" + System.Environment.CurrentDirectory.Replace("\\", "/");
            else if (Application.isMobilePlatform || Application.isConsolePlatform)
                return Application.streamingAssetsPath;
            else
                return "file:///" + Application.streamingAssetsPath;
            // is RIght? todo
        }

        public static void SetSourceAssetbundleDirectory(string relativePath)
        {
            _baseDownLoadingURL = GetStreamingAssetsPath() + relativePath;
        }

        public static void SetSourceAssetbundleURL(string absolutePath)
        {
            if(!absolutePath.EndsWith("/"))
            {
                absolutePath += "/";
            }

            _baseDownLoadingURL = absolutePath + AssetbundleUtility.GetCurrentPlatformName() + "/";
        }

        /// <summary>
        /// build a file name "AssetBundleServerURL" put it into Resources folder,and this function will read it
        /// as DevelopmentAssetbundleServer URL
        /// </summary>
        public static void SetDevelopmentAssetbundleServer()
        {
#if UNITY_EDITOR
            if (SimulateAssetbundleInEditor)
                return;
#endif
            TextAsset urlFile = (TextAsset)Resources.Load("AssetBundleServerURL");
            string url = (urlFile != null) ? urlFile.text.Trim() : null;
            if(null==url||0==url.Length)
            {
                Log(LogType.Error, "Development Server URL conld not be found");
            }
            else
            {
                SetSourceAssetbundleURL(url);
            }
        }


        public static LoadedAssetbundle GetLoadedAssetbundle(string assetbundleName,out string error)
        {
            error = null;
            return null;
        }
        
    }
}
